package com.ruoyi.order.service.impl;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
import com.alibaba.fastjson.JSON;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.order.domain.OrderService;
import com.ruoyi.order.mapper.OrderServiceMapper;
import com.ruoyi.shop.api.RemoteDrawalService;
import com.ruoyi.shop.api.domain.CheDrawal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.ruoyi.order.mapper.CheStatementMapper;
import com.ruoyi.order.domain.CheStatement;
import com.ruoyi.order.service.ICheStatementService;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class CheStatementServiceImpl implements ICheStatementService {

    @Autowired
    private CheStatementMapper cheStatementMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private OrderServiceMapper orderServiceMapper;

    @Autowired
    private RemoteDrawalService remoteDrawalService;

    /**
     * 查询收支明细
     *
     * @param id 收支明细主键
     * @return 收支明细
     */
    @Override
    public CheStatement selectCheStatementById(Long id) {
        try {
            // 查询收支明细基本信息
            CheStatement cheStatement = cheStatementMapper.selectCheStatementById(id);
            if (cheStatement == null) {
                log.warn("CheStatement not found for id: {}", id);
                return null;
            }

            // 查询 OrderService 数据并注入
            Long orderId = cheStatement.getOrderId();
            OrderService orderService = getOrderServiceFromCache(orderId);
            cheStatement.setOrderService(orderService);

            // 查询 CheDrawal 数据并注入
            Long drawalId = cheStatement.getDrawalId();
            CheDrawal cheDrawal = getCheDrawalFromCache(drawalId);
            cheStatement.setCheDrawal(cheDrawal);

            return cheStatement;
        } catch (Exception e) {
            log.error("Error fetching CheStatement for id: {}", id, e);
            return null;
        }
    }

    /**
     * 查询收支明细列表
     *
     * @param cheStatement 收支明细
     * @return 收支明细列表
     */
    @Override
    public List<CheStatement> selectCheStatementList(CheStatement cheStatement) {
        List<CheStatement> cheStatements = cheStatementMapper.selectCheStatementList(cheStatement);

        for (CheStatement statement : cheStatements) {
            try {
                // 查询并缓存 OrderService 数据
                Long orderId = statement.getOrderId();
                OrderService orderService = getOrderServiceFromCache(orderId);
                statement.setOrderService(orderService);

                // 查询并缓存 CheDrawal 数据
                Long drawalId = statement.getDrawalId();
                CheDrawal cheDrawal = getCheDrawalFromCache(drawalId);
                statement.setCheDrawal(cheDrawal);
            } catch (Exception e) {
                log.error("Error processing CheStatement: {}", statement, e);
            }
        }

        return cheStatements;
    }

    /**
     * 新增收支明细
     *
     * @param cheStatement 收支明细
     * @return 结果
     */
    @Override
    public int insertCheStatement(CheStatement cheStatement) {
        try {
            return cheStatementMapper.insertCheStatement(cheStatement);
        } catch (Exception e) {
            log.error("Error inserting CheStatement", cheStatement, e);
            throw e; // 保证事务回滚
        }
    }

    /**
     * 修改收支明细
     *
     * @param cheStatement 收支明细
     * @return 结果
     */
    @Override
    public int updateCheStatement(CheStatement cheStatement) {
        try {
            return cheStatementMapper.updateCheStatement(cheStatement);
        } catch (Exception e) {
            log.error("Error updating CheStatement: {}", cheStatement, e);
            throw e; // 保证事务回滚
        }
    }

    /**
     * 批量删除收支明细
     *
     * @param ids 需要删除的收支明细主键
     * @return 结果
     */
    @Override
    public int deleteCheStatementByIds(Long[] ids) throws Exception
    {
        try {
            return cheStatementMapper.deleteCheStatementByIds(ids);
        } catch (Exception e) {
            log.error("Error deleting CheStatements by ids: {}", (Object) ids, e);
            handleForeignKeyConstraintException(e); // 处理外键约束异常
            return 0;
        }
    }

    /**
     * 删除收支明细信息
     *
     * @param id 收支明细主键
     * @return 结果
     */
    @Override
    public int deleteCheStatementById(Long id) throws Exception
    {
        try {
            return cheStatementMapper.deleteCheStatementById(id);
        } catch (Exception e) {
            log.error("Error deleting CheStatement by id: {}", id, e);
            handleForeignKeyConstraintException(e); // 处理外键约束异常
            return 0;
        }
    }

    @Override
    public List<CheStatement> selectByShop(Long shopId) {
        return cheStatementMapper.selectCheStatementListByOrderIdOrDrawalId(shopId);
    }

    // 从 Redis 获取 OrderService，如果缓存没有则查询数据库并更新缓存
    private OrderService getOrderServiceFromCache(Long orderId) {
        String cacheKey = "orderService:" + orderId;
        OrderService orderService = (OrderService) redisTemplate.opsForValue().get(cacheKey);

        if (orderService == null) {
            orderService = orderServiceMapper.selectOrderServiceById(orderId);
            if (orderService != null) {
                redisTemplate.opsForValue().set(cacheKey, orderService, 20, TimeUnit.MINUTES);
            }
        }
        return orderService;
    }

    // 从 Redis 获取 CheDrawal，如果缓存没有则查询远程服务并更新缓存
    private CheDrawal getCheDrawalFromCache(Long drawalId) {
        String cacheKey = "cheDrawal:" + drawalId;
        CheDrawal cheDrawal = (CheDrawal) redisTemplate.opsForValue().get(cacheKey);

        if (cheDrawal == null) {
            AjaxResult info = remoteDrawalService.getInfo(drawalId, null);
            Object drawal = info.get(AjaxResult.DATA_TAG);

            if (drawal != null) {
                cheDrawal = JSON.parseObject(JSON.toJSONString(drawal), CheDrawal.class);
                redisTemplate.opsForValue().set(cacheKey, cheDrawal, 10, TimeUnit.MINUTES);
            }
        }
        return cheDrawal;
    }

    // 处理外键约束异常
    private void handleForeignKeyConstraintException(Exception e) throws Exception
    {
        if (e.getMessage().contains("存在外键约束")) {
            log.warn("Cannot delete due to foreign key constraint violation.", e.getMessage());
        } else {
            throw e;
        }
    }
}
